﻿using CPPEI.Coolzon.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.ServiceProxy
{
    /// <summary>
    /// 方案同步服务代理类，
    /// 这个类存放了方案同步服务的基本信息，每一个方案同步服务配置都会对应一个实例。
    /// </summary>
    public class SyncServiceProxy
    {
        public string IP { get; private set; }
        public int Port { get; private set; }
        private Configuration.Client.ServiceConfig _serviceConfig;
        public SyncServiceRef.SyncServiceClient Client { get; private set; }

        public ServiceProxyState State { get; set; }

        /// <summary>
        /// 构建主服务代理
        /// </summary>
        /// <param name="serviceConfig"></param>
        public SyncServiceProxy(Configuration.Client.ServiceConfig serviceConfig)
        {
            this.IP = serviceConfig.IP;
            this.Port = serviceConfig.Port;
            _serviceConfig = serviceConfig;

            this.Client = CreateSyncServiceClient(_serviceConfig);

            State = ServiceProxyState.Inited;
        }

        /// <summary>
        /// 打开连接
        /// </summary>
        /// <returns></returns>
        internal void Open()
        {
            if(this.State == ServiceProxyState.Inited)
            {
                try
                {
                    this.Client.Open();
                    this.State = ServiceProxyState.Connected;
                }
                catch (Exception ex)
                {
                    Common.Logger.ErrorToTag(Library.LogTAG, "SyncServiceProxy{0}:{1}打开失败,ex:{2}",
                        IP,
                        Port,
                        ex);
                    this.State = ServiceProxyState.Disconnected;
                }
            }
        }

        /// <summary>
        /// 设置连接状态为“ServiceProxyState.Disconnected”，同时将Client对象关闭
        /// </summary>
        internal void Disconnect()
        {
            Logger.DebugToTag(Library.LogTAG, "SyncServiceProxy{0}:{1},设置State为{2}", this.IP,
                this.Port,
                ServiceProxyState.Disconnected);
            this.State = ServiceProxyState.Disconnected;
            if (this.Client != null)
            {
                this.Client.Abort();
                this.Client.Close();
                this.Client = null;
                Logger.DebugToTag(Library.LogTAG, "SyncServiceProxy{0}:{1},关闭Client对象", this.IP,
                    this.Port);
            }
        }

        /// <summary>
        /// 关闭Client对象
        /// </summary>
        internal void Close()
        {
            Logger.DebugToTag(Library.LogTAG, "SyncServiceProxy{0}:{1}关闭", this.IP,
                this.Port);
            if (this.Client != null)
            {
                this.Client.Abort();
                this.Client.Close();
                this.Client = null;
                Logger.DebugToTag(Library.LogTAG, "SyncServiceProxy{0}:{1},关闭Client对象", this.IP,
                    this.Port);
            }
        }

        /// <summary>
        /// 创建方案同步服务客户端对象
        /// </summary>
        /// <param name="serviceConfig"></param>
        /// <returns></returns>
        private static SyncServiceRef.SyncServiceClient CreateSyncServiceClient(Configuration.Client.ServiceConfig serviceConfig)
        {
            System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding();
            (tcpBinding as NetTcpBinding).ReceiveTimeout = TimeSpan.FromSeconds(300);
            (tcpBinding as NetTcpBinding).SendTimeout = TimeSpan.FromSeconds(300);
            (tcpBinding as NetTcpBinding).Security.Mode = SecurityMode.None;
            (tcpBinding as NetTcpBinding).MaxBufferSize = 1024 * 1024 * 1024;
            (tcpBinding as NetTcpBinding).MaxReceivedMessageSize = 1024 * 1024 * 1024;
            EndpointAddress address = new EndpointAddress(string.Format("net.tcp://{0}:{1}/{2}/", serviceConfig.IP, serviceConfig.Port, serviceConfig.Path));

            SyncServiceRef.SyncServiceClient syncServiceClient = new SyncServiceRef.SyncServiceClient(tcpBinding, address);
            return syncServiceClient;
        }
    }
}
